home *** CD-ROM | disk | FTP | other *** search
- #include <osbind.h>
- #include <xbra.h>
- #include <basepage.h>
- #include <sysvars.h>
-
- /**
- ** (sjk)++ This is a very cheap alarm() type call, when called with
- ** zero argument, turn off main body of interrupt code. When
- ** called with a positive argument, turn on interupt code,
- ** and start it counter to modify the variable echo_flag,
- ** when the counter expires. (set echo_flag = 1)
- **/
-
- static void timer __PROTO((void));
- static void term __PROTO((void));
- static void install_handlers __PROTO((void));
- static void remove_handlers __PROTO((void));
- static void unlink_handler __PROTO((xbra_struct *me, int exc));
- static void install_timer __PROTO((void));
- void install_alarm __PROTO((void));
-
- extern BASEPAGE *_base;
- static BASEPAGE **act_pd;
- static BASEPAGE *my_base;
- static short installed = 0;
-
- extern int echo_flag;
-
- long int t_ms;
- long int enabled;
-
- /* XBRA pointers to our new interupt handlers, 1. timer for alarm */
- /* 2. term - remove */
- /* handlers. */
- static xbra_struct timer_xbra = _XBRA_INIT(timer);
- static xbra_struct term_xbra = _XBRA_INIT(term);
-
-
- void install_alarm()
- {
- long *sysbase;
-
- sysbase = (long *) get_sysvar((void *) _sysbase);
- switch (sysbase[6])
- { case 0x11201985L:
- case 0x02061986L:
- case 0x04241986L:
- act_pd = (BASEPAGE **) 0x602C;
- break;
- default:
- act_pd = (BASEPAGE **) sysbase[10];
- }
- (void) install_timer();
- }
-
- /* use the Xbra convention to link into the evnt_timer loop (20ms) */
- /* use the Xbra convention to link into the terminate handler. */
- void install_timer()
- {
- timer_xbra.next = (xptr) Setexc(0x100, _XBRA_VEC(timer_xbra));
- term_xbra.next = (xptr) Setexc(0x102, _XBRA_VEC(term_xbra));
- my_base = (BASEPAGE *)_base;
- }
-
- /* call unlink to remove our hooked interupt handlers. */
- void remove_handlers()
- { if (_base == *act_pd)
- {
- if (_base != my_base)
- _base -= 2;
- else
- {
- unlink_handler(&timer_xbra,0x100);
- unlink_handler(&term_xbra,0x102);
- installed = 0;
- }
- }
- }
-
- /*
- * unlink a handler in a xbra friendly manner from the exc chain
- */
- static void unlink_handler(me, exc)
- xbra_struct *me;
- int exc;
- {
- xbra_struct *this, *prev;
- long save_ssp;
- unsigned long ulong;
-
- ulong = (unsigned long)Setexc(exc,-1L);
- this = (struct __xbra *)(ulong - 12L );
- if(this == me)
- { /* at the head, just unlink */
- Setexc(exc, me->next);
- return;
- }
- /* otherwise find me in the chain and unlink */
- save_ssp = Super(0L);
- for(prev = this; this && (this != me); prev = this, this = this->next)
- {
- /* validate the xbra */
- if(this->xbra_magic != _XBRA_MAGIC)
- { /* shame on you */
- Super(save_ssp);
- Setexc(exc, me->next); /* nuke it, otherwise it may call ME */
- return; /* after i am deinstalled */
- }
- }
-
- if(this == me)
- { /* unlink me from middle of the chain */
- prev->next = this->next;
- Super(save_ssp);
- return;
- }
- /* we are screwed */
- Super(save_ssp);
- Cconws("\r\nwhat the fuck!\r\n\n");
- }
-
-
- void my_alarm(time)
- int time;
- { if (!installed)
- { install_alarm();
- installed = 1;
- }
- if (time == 0)
- enabled = 0;
- else
- { t_ms = 50*time;
- enabled = 1;
- }
- }
-
- static void term()
- {
- if (_base != *act_pd)
- { __asm__ volatile("\
- unlk a6
- jmp %0@"
- :
- : "a"(term_xbra.next));
- }
- if (installed)
- remove_handlers();
- __asm__ volatile("\
- unlk a6
- jmp %0@"
- :
- : "a"(term_xbra.next));
- }
-
-
- /*
- * timer handler
- * in etv_timer timer handoff vector chain (called every 4th tick)
- * stack at this point:
- * <exception frame user pc, sr> 2
- * <saved d0-d7/a0-a6> 60
- * <timer calibration .w> 2
- * <return address to timer C intr routine> 4
- * ---
- * 68 (offset to user pc)
- */
- __asm__ ("\
- .text; .even
- _timer:
-
- tstl _enabled /* is it zero ? */
- beq 1f /* No! We have something to do. */
-
- subql #1,_t_ms /* Decrement our timer... */
- bne 1f /* It is not out time! */
-
- movl #0,_enabled /* disbale us. */
- movl #1,_echo_flag /* our whole goal. */
-
- 1:
- movl _timer_xbra+8,sp@- /* call next handler in chain */
- rts ");
-